#ifndef RECURSOALMACENAMIENTO_H_
#define RECURSOALMACENAMIENTO_H_

#include "Indice.h"
#include "EstrategiaAlmacenamiento.h"
#include "Almacenamiento.h"

namespace Toolkit
{

class EstrategiaRecurso;
	
class RecursoAlmacenamiento
{

public:	
	RecursoAlmacenamiento(Almacenamiento *primario, EstrategiaRecurso *estrategiaRecurso, 
			EstrategiaAlmacenamiento *estrategiaAlmacenamiento, 
			Indice *indice = NULL, Almacenamiento *secundario = NULL);
	
	virtual ~RecursoAlmacenamiento();
	
	/**
	 * Guarda, verificando unicidad.
	 * Si la clave es duplicada se lanza una excepción. 
	 * */
    virtual void guardarDato(const Dato &dato, const Clave &clave);
    
    /**
     * Busca el dato con la clave dada. 
     * Si lo encuentra devuelve true y lo almacena en el dato pasado.
     * Si no lo encuentra, devuelve false.
     * */
    virtual bool recuperarDato(const Clave &clave, Dato &dato) const;
    
    /**
     * Se elimina el dato cuya clave es la especificada,
     * y se lo devuelve almacenado en el dato pasado.
     * Si no se encuentra en los almacenamientos, no se hace nada.
     * */
    virtual void eliminarDato(const Clave &clave, Dato &dato);
        
    /**
     * Reemplaza el dato cuya clave es especificada, por el nuevo dato pasado.
     * En caso de no encontrarse la clave, se la agrega en un nuevo registro.
     * */
    virtual void actualizarDato(const Dato &dato, const Clave &clave);	

    virtual bool bSharpGetSiguienteDato(Dato &dato, const Clave &clave) const;
	
    void setControlUnicidad(const bool& controlUnicidad);

    bool getControlarUnicidad() const;



	
private:
	EstrategiaRecurso* estrategiaRecurso;
	EstrategiaAlmacenamiento* estrategiaAlmacenamiento;
	Indice* indice;	
	
	/***
	 * Almacenamiento primario. De haber indice, se asocia a este almacenamiento.
	 * Si la estrategia es de un almacenamiento, se usara a este. 
	 * */
	Almacenamiento* primario;
	
	/**
	 * Se supone el almacenamiento de acceso rápido (probablemente un buffer).
	 * No se le asocia un indice. Si se trabaja con estrategias de dos almacenamientos
	 * se utilizará primero a este para las lecturas y escrituras.
	 * */
	Almacenamiento* secundario;

	friend class EstrategiaRecurso;
	friend class EstrategiaRecursoUnAlmacenamiento;
	friend class EstrategiaRecursoEscrituraDirecta;
	friend class EstrategiaRecursoEscrituraDiferida;

};
	
}

#endif /*RECURSOALMACENAMIENTO_H_*/
